home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
BSDRIVE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-04
|
12KB
|
453 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: bsdrive.c
// Title: Base library
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
//
// This module contains .
//
// The code in this module should be written entirely in C.
// Do not use any C++ constructs.
//
// This module is portable to:
// DOS 3.X+
// MS Windows 3.X+
// OS/2 2.X+
// OS/2 2.0 PM
// SCO UNIX.
//
// The following compilers are supported:
// MSC 6.0A
// MSC/C++ 7.0
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
// SCO UNIX cc
//
//----------------------------------------------------------------------------
#include <bs.h>
//----------------------------------------------------------------------------
// Globals
//----------------------------------------------------------------------------
#define DOS_DATA_SEG 0x0050
#if OS_DOS || OS_WINDOWS
static SHORT FN_L DriveGetLogical(SHORT);
#endif
static SHORT FN_L DriveSetLogical(SHORT);
//----------------------------------------------------------------------------
// Description: Query current drive
// Parameters:
// Returns: Current drive. 1=A, 2=B, ...
//----------------------------------------------------------------------------
SHORT FN_E DriveGet(void)
{
#if OS_UNIX
return 0;
#else
unsigned drive;
_dos_getdrive(&drive);
return (SHORT)drive;
#endif
}
//----------------------------------------------------------------------------
// Description: Get logical drive for current drive.
// Parameters: sDrive Drive letter. 1..26
// Returns: Previous logical drive.
//----------------------------------------------------------------------------
#if OS_DOS || OS_WINDOWS
static SHORT FN_L DriveGetLogical(SHORT sDrive)
{
SHORT sCurDrive; // Current drive attached to block device
union REGS regs; // Registers for interrupt calls.
if (_osmajor > 3 || _osmajor == 3 && _osminor >= 20)
{
// IOCTL request 0x0E (get logical drive).
regs.x.ax = 0x440E;
// Drive number (1 = A, 2 = B, etc) is in BL.
regs.h.bl = (UCHAR)sDrive;
intdos(®s, ®s);
if (regs.x.cflag) // Carry flag set, error in _doserrno.
sCurDrive = 0; // Return code of 0 in AL means only
else // one drive attachedto block device.
sCurDrive = regs.h.al == 0 ? sDrive : regs.h.al + ('A' - 1);
}
else if (sDrive == 1 || sDrive == 2)// For lower versions of DOS, only drives
{ // A and B are interchangeable.
int86(0x11, ®s, ®s);
// Bit 0 in AX is 1 if diskette drives are present.
if (regs.x.ax & 0x0001)
{ // Only one diskette installed.
if (((regs.x.ax & 0xC0) >> 6) == 0)
{
// sCurDrive = sDrive == 1 || sDrive == 2 ?
// peekb(DOS_DATA_SEG, 0x0004) + 1 : sDrive;
}
else
sCurDrive = sDrive; // More than one diskette installed.
}
else // No diskette drive.
sCurDrive = 0;
}
else
sCurDrive = sDrive;
return sCurDrive;
}
#endif
//----------------------------------------------------------------------------
// Description: Determine if a drive is remote
// Parameters: sDrive Drive may be 1..26 (A..Z), A..Z, or a..z.
// Drive is converted to a number 1..26.
// Returns: TRUE if drive is valid and remote
//----------------------------------------------------------------------------
BOOL FN_E DriveIsRemote(SHORT sDrive)
{
#if OS_UNIX
NOTUSED(sDrive);
return FALSE;
#else
BOOL fResult = FALSE;
if (!DriveIsValid(sDrive, &sDrive))
return FALSE;
#if OS_DOS || OS_WINDOWS
if (_osmajor > 3 || _osmajor == 3 && _osminor >= 20)
{
_asm {
mov ax, 4409h
mov bx, [sDrive]
int 21h
jc ERROR_EXIT
and dx, 1000h
jz ERROR_EXIT
mov [fResult], 1
}
}
ERROR_EXIT:
#endif
return fResult;
#endif
}
//----------------------------------------------------------------------------
// Description: Determine if a drive is valid
// Not valid under unix. Always returns TRUE.
// Parameters: sDrive Drive may be 1..26 (A..Z), A..Z, or a..z.
// Drive is converted to a number 1..26.
// psDrive Drive id converted to a number 1..26
// If null, value is not returned.
// Returns: TRUE if drive is valid
//----------------------------------------------------------------------------
BOOL FN_E DriveIsValid(SHORT sDrive, PSHORT psDrive)
{
#if OS_UNIX
NOTUSED(sDrive);
if (psDrive)
psDrive[0] = (SHORT)0;
return TRUE;
#else
BOOL fResult;
SHORT sOldDrive = DriveGet();
// Validate drive letter
if (sDrive == 0)
sDrive = sOldDrive;
if (sDrive >= 'A' && sDrive <= 'Z')
sDrive = (SHORT)(sDrive - 'A' + 1);
if (sDrive >= 'a' && sDrive <= 'z')
sDrive = (SHORT)(sDrive - 'a' + 1);
if (sDrive < 1 || sDrive > 26)
return FALSE;
if (psDrive)
*psDrive = sDrive;
fResult = (_chdrive(sDrive) == SUCCESS);
_chdrive(sOldDrive);
return fResult; // Done
#endif
}
//----------------------------------------------------------------------------
// Description: Set current drive
// This function is meaningless under UNIX.
// Parameters: sDrive Drive may be 1..26 (A..Z), A..Z, or a..z.
// Drive is converted to a number 1..26.
// Returns: TRUE if drive is valid
//----------------------------------------------------------------------------
BOOL FN_E DriveSet(SHORT sDrive)
{
#if OS_UNIX
NOTUSED(sDrive);
return FALSE;
#else
if (sDrive >= 'A' && sDrive <= 'Z')
sDrive = (SHORT)(sDrive - 'A' + 1);
if (sDrive >= 'a' && sDrive <= 'z')
sDrive = (SHORT)(sDrive - 'a' + 1);
if (sDrive < 1 || sDrive > 26)
return FALSE;
DriveSetLogical(sDrive);
return _chdrive(sDrive) == SUCCESS;
#endif
}
//----------------------------------------------------------------------------
// Description: Set logical drive for current drive.
// Parameters: sDrive Drive letter.
// Returns: Previous logical drive.
//----------------------------------------------------------------------------
static SHORT FN_L DriveSetLogical(SHORT sDrive)
{
#if OS_DOS || OS_WINDOWS
char sCurDrive; // Current drive attached to block device.
union REGS regs; // Registers for interrupt calls.
sCurDrive = (char)DriveGetLogical(sDrive);
if (sCurDrive != 0 && sCurDrive != sDrive)
{ // Check for DOS version 3.20 or above.
if (_osmajor > 3 || _osmajor == 3 && _osminor >= 20)
{ // IOCTL request 0x0F (set logical drive).
regs.x.ax = 0x440F; // Drive number (1 = A, 2 = B, etc) is in BL.
regs.h.bl = (UCHAR)sDrive;
intdos(®s, ®s);
if (regs.x.cflag) // Carry flag set, error in _doserrno.
sDrive = 0;
}
// else if (sDrive == 1 || sDrive == 2)
// pokeb(DOS_DATA_SEG, 0x0004, sDrive - 1);
}
return sCurDrive;
#else
return sDrive;
#endif
}
//----------------------------------------------------------------------------
// Description: Get drive type
// Parameters: sDrive Drive may be 1..26 (A..Z), A..Z, or a..z.
// Drive is converted to a number 1..26.
// plTotal If not null, returns total disk size in bytes.
// plFree If not null, returns free disk size in bytes.
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
SHORT FN_E DriveSize(SHORT sDrive, PLONG plTotal, PLONG plFree)
{
LONG lTotal = 0;
LONG lFree = 0;
#if OS_UNIX==0
struct diskfree_t dtable;
#endif
if (plTotal) // Set initial values
plTotal[0] = lTotal;
if (plFree)
plFree[0] = lFree;
#if OS_UNIX
NOTUSED(sDrive);
#else
if (!DriveIsValid(sDrive, &sDrive))
return DRV_OTHER;
CritErrReset();
if (_dos_getdiskfree((unsigned)sDrive, &dtable)
|| CritErr())
{
Error("Drive %c: not available.", 'A' + sDrive - 1);
return DRV_OTHER;
}
lTotal = (long)dtable.sectors_per_cluster * (long)dtable.bytes_per_sector
* (long)dtable.total_clusters;
lFree = (long)dtable.sectors_per_cluster * (long)dtable.bytes_per_sector
* (long)dtable.avail_clusters;
#endif
if (plTotal)
plTotal[0] = lTotal;
if (plFree)
plFree[0] = lFree;
return TRUE;
}
//----------------------------------------------------------------------------
// Description: Get drive type
// Parameters: sDrive Drive may be 1..26 (A..Z), A..Z, or a..z.
// Drive is converted to a number 1..26.
// Returns: Drive type
//----------------------------------------------------------------------------
SHORT FN_E DriveType(SHORT sDrive)
{
#if OS_UNIX
NOTUSED(sDrive);
return DRV_OTHER;
#elif OS_DOS || OS_WINDOWS
SHORT sDriveType = DRV_OTHER;
if (!DriveIsValid(sDrive, &sDrive))
return DRV_OTHER;
if (_osmajor > 3 || _osmajor == 3 && _osminor >= 20)
{
BYTE bBuf[0x26];
PBYTE pb = bBuf;
memset(bBuf, 0, sizeof(bBuf));
_asm {
push si
push di
push ds
mov ax, 440Dh
mov bx, [sDrive]
mov cx, 0860h
lds dx, [pb]
mov di, dx // OS/2 comp box
mov si, ds // OS/2 comp box
int 21h
pop ds
pop di
pop si
jc ERROR_EXIT
}
sDriveType = (SHORT)bBuf[1];
}
if (sDriveType < DRV_FIRST || sDriveType > DRV_LAST)
sDriveType = DRV_OTHER;
ERROR_EXIT:
return sDriveType;
#else
NOTUSED(sDrive);
return DRV_OTHER;
#endif
}
//----------------------------------------------------------------------------
// Description: Run standard test suite
// Parameters: sTest Test to run.
// 0 Run all default tests (except).
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if COMPILE_TEST
BOOL FN DriveTest(SHORT sTest)
{
#if OS_UNIX == 0
SHORT sDrive = 0;
SHORT i;
LONG lTotal, lFree;
if ((sDrive = DriveGet()) != 0)
Output("Current drive is %c:\n", sDrive + 'A' - 1);
else
Output("Current drive is cannot be determined!\n");
for (i = 'A'; i <= 'Z'; ++i)
if (DriveIsValid(i, NULL))
{
Output("%c: is a valid drive.", i);
if (DriveIsRemote(i))
Output(" Drive is remote.");
Output(" Drive is ");
switch (DriveType(i))
{
case DRV_360:
Output("5.25\" 360 Kb.");
break;
case DRV_12:
Output("5.25\" 1.2 Mb.");
break;
case DRV_720:
Output("3.5\" 720 Kb.");
break;
case DRV_8_SD:
Output("8\" SD");
break;
case DRV_8_DD:
Output("8\" DD.");
break;
case DRV_FIXED:
Output("FIXED.");
break;
case DRV_TAPE:
Output("TAPE.");
break;
case DRV_144:
Output("3.5\" 1.44 Mb.");
break;
default:
case DRV_OTHER:
Output("OTHER.");
break;
}
Output("\n");
if (DriveSize(i, &lTotal, &lFree))
Output(" %ld bytes total, %ld bytes free.\n", lTotal, lFree);
}
#endif
NOTUSED(sTest);
return TRUE;
}
#endif
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------